package com.wjk.easy.blue.rd915demo;

import android.os.SystemClock;
import android.util.Log;

public class BTClient {
    public static BluetoothLeService mBluetoothLeService = null;
    public static byte[] RecvBuff = new byte[5000];
    public static int RecvLength = 0;
    private static long time1 = 0;
    public static byte ComAddr;
    public static long CmdTime = 500;
    public static String DeviceName = "";
    public static String tagid = "";
    public static boolean CmdIng = false;
    public static String ActiveModeStr = "";

    public static String GetDevName() {
        return DeviceName;
    }

    //Len：2个字节，高字节在前，包长度，包括Len本身。即包长度等于5+m+n。
    //Cmd：1个字节，命令代码。用于通知蓝牙助手透传命令帧Frame[]前需要进行的操作。
    //Data[]：m个字节，对应于Cmd命令码的操作数据。
    //Frame[]：n个字节，要发送给读写器的完整的命令帧。该部分数据将直接透传给读写器，因此要保证数据格式和内容的正确。
    //CRC-16：2个字节，低字节在前。CRC16是从Len到Frame []的CRC16值。

    public static String init_com(byte Baudrate, byte Parity) {
        byte[] data = new byte[7];
        data[0] = 0;
        data[1] = 7;
        data[2] = 1;
        data[3] = Baudrate;
        data[4] = Parity;
        getCRC(data, 5);
        return bytesToHexString(data, 0, 7);
    }

    public static void SetDevName(String name) {
        DeviceName = name;
    }

    public static void settag_id(String name) {
        tagid = name;
    }

    public static String gettag_id() {
        return tagid;
    }

    public static void getCRC(byte[] data, int Len) {
        try {
            int i, j;
            int current_crc_value = 0xFFFF;
            for (i = 0; i < Len; i++) {
                current_crc_value = current_crc_value ^ (data[i] & 0xFF);
                for (j = 0; j < 8; j++) {
                    if ((current_crc_value & 0x01) != 0)
                        current_crc_value = (current_crc_value >> 1) ^ 0x8408;
                    else
                        current_crc_value = (current_crc_value >> 1);
                }
            }
            data[i++] = (byte) (current_crc_value & 0xFF);
            data[i] = (byte) ((current_crc_value >> 8) & 0xFF);
        } catch (Exception e) {

        }
    }

    public static boolean CheckCRC(byte[] data, int len) {
        try {
            byte[] daw = new byte[256];
            memcpy(data, 0, daw, 0, len);
            getCRC(daw, len);
            if (0 == daw[len + 1] && 0 == daw[len]) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    public static void ArrayClear(byte[] Msg, int Size) {
        for (int i = 0; i < Size; i++) {
            Msg[i] = 0;
        }
    }


    public static void memcpy(byte[] SourceByte, int StartBit_1, byte[] Targetbyte, int StartBit_2, int Length) {
        try {
            for (int m = 0; m < Length; m++) {
                Targetbyte[StartBit_2 + m] = SourceByte[StartBit_1 + m];
            }
        } catch (Exception e) {

        }
    }

    public static void memcpy(byte[] SourceByte, byte[] Targetbyte, int Length) {
        try {
            for (int m = 0; m < Length; m++) {
                Targetbyte[m] = SourceByte[+m];
            }
        } catch (Exception e) {

        }
    }

    public static String bytesToHexString(byte[] src, int offset, int length) {
        try {
            String stmp = "";
            StringBuilder sb = new StringBuilder("");
            for (int n = 0; n < length; n++) {
                stmp = Integer.toHexString(src[n + offset] & 0xFF);
                sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            }
            return sb.toString().toUpperCase().trim();
        } catch (Exception e) {
            return "";
        }
    }


    public static byte[] hexStringToBytes(String hexString) {
        try {
            if (hexString == null || hexString.equals("")) {
                return null;
            }
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
            for (int i = 0; i < length; i++) {
                int pos = i * 2;
                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
            }
            return d;
        } catch (Exception e) {
            return null;
        }
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static int GetData() {
        try {
            time1 = System.currentTimeMillis();
            while ((System.currentTimeMillis() - time1) < 2000) {
                SystemClock.sleep(20);
                int recvLen = UhfService.RecvString.length() / 2;
                if (recvLen > 0) {
                    byte[] buffer = new byte[recvLen];
                    buffer = hexStringToBytes(UhfService.RecvString);
                    memcpy(buffer, 0, RecvBuff, 0, recvLen);
                    RecvLength = recvLen;
                    int activelen = buffer[0] + 1;
                    if (CheckCRC(RecvBuff, activelen)) {
                        Log.d("read data:", UhfService.RecvString);
                        CmdIng = false;
                        return 0;
                    }
                }
            }
            CmdIng = false;
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public static int GetReaderInfo(byte[] Version, byte[] Power, byte[] Fre) {
        try {
            byte[] Msg = new byte[6];
            Msg[0] = 0x04;
            Msg[1] = (byte) 0xFF;
            Msg[2] = 0x21;
            Msg[3] = 0x19;
            Msg[4] = (byte) 0x95;
            CmdTime = 500;
            UhfService.target_chara.setValue(Msg);
            ArrayClear(RecvBuff, 5000);
            RecvLength = 0;
            UhfService.RecvString = "";
            mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                Version[0] = RecvBuff[4];
                Version[1] = RecvBuff[5];
                Power[0] = RecvBuff[10];
                Fre[0] = RecvBuff[8];
                Fre[1] = RecvBuff[9];
                return RecvBuff[3];
            }
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public static int SetPower(byte Pwr) {
        try {
            byte[] Msg = new byte[6];
            Msg[0] = 0x05;
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 0x2F;
            Msg[3] = Pwr;
            getCRC(Msg, 4);
            CmdTime = 500;
            UhfService.target_chara.setValue(Msg);
            ArrayClear(RecvBuff, 5000);
            RecvLength = 0;
            UhfService.RecvString = "";
            mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                return RecvBuff[3];
            }
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public static int SetRegion(byte MaxFre, byte MinFre) {
        try {
            byte[] Msg = new byte[7];
            Msg[0] = 0x06;
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 0x22;
            Msg[3] = MaxFre;
            Msg[4] = MinFre;
            getCRC(Msg, 5);
            CmdTime = 500;
            UhfService.target_chara.setValue(Msg);
            ArrayClear(RecvBuff, 300);
            RecvLength = 0;
            UhfService.RecvString = "";
            mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                return RecvBuff[3];
            }
            return -1;
        } catch (Exception e) {
            return -1;
        }

    }

    public static int SetBaudRate(byte BaudRate) {
        try {
            byte[] Msg = new byte[10];
            Msg[0] = 0x05;
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 0x28;
            Msg[3] = BaudRate;
            getCRC(Msg, 4);
            CmdTime = 500;
            UhfService.target_chara.setValue(Msg);
            ArrayClear(RecvBuff, 300);
            RecvLength = 0;
            UhfService.RecvString = "";
            mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                return RecvBuff[3];
            }
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public static String[] ScanUID(){
        byte[] EPCList = new byte[5000];
        int[] CardNum = new int[2];
        int[] EPCLength = new int[2];
        CardNum[0] = 0;
        EPCLength[0] = 0;
        int result = Inventory_G2((byte) 4, (byte) 0, (byte) 0, (byte) 0, (byte) 0, CardNum, EPCList, EPCLength);
        if (((CardNum[0] & 255) > 0) && (result != 0x30)) {
            int Scan6CNum = CardNum[0] & 255;
            String[] lable = new String[Scan6CNum];
            StringBuffer bf;
            int j = 0, k;
            String str;
            byte[] epc;
            Log.i("zdy", "num = " + Scan6CNum + ">>>>>>" + "len = " + EPCLength[0]);
            for (int i = 0; i < Scan6CNum; i++) {
                bf = new StringBuffer("");
                Log.i("yl", "length = " + EPCList[j]);
                epc = new byte[EPCList[j] & 0xff];
                for (k = 0; k < (EPCList[j] & 0xff); k++) {
                    str = Integer.toHexString(EPCList[j + k + 1] & 0xff);
                    if (str.length() == 1) {
                        bf.append("0");
                    }
                    bf.append(str);
                    epc[k] = EPCList[j + k + 1];
                }
                lable[i] = bf.toString().toUpperCase();
                //epcBytes.put(lable[i], epc);
                j = j + k + 2;
            }
            return lable;
        }
        return null;
    }

    public static int GetInventoryData() {
        try {
            time1 = System.currentTimeMillis();
            while ((System.currentTimeMillis() - time1) < 3000) {
                SystemClock.sleep(10);
                int recvLen = UhfService.RecvString.length() / 2;
                if (recvLen > 0) {
                    byte[] buffer = new byte[recvLen];
                    buffer = hexStringToBytes(UhfService.RecvString);
                    memcpy(buffer, 0, RecvBuff, 0, recvLen);
                    RecvLength = recvLen;
                    byte[] Buff1 = new byte[5000];
                    memcpy(RecvBuff, 0, Buff1, 0, recvLen);
                    int nTurn = recvLen;
                    while (nTurn > 0) {
                        byte[] Buff2 = new byte[5000];
                        if (nTurn < (Buff1[0] & 255) + 1) {
                            break;
                        }
                        if (((Buff1[3] != 0x03) && (Buff1[3] != 0x04)) && ((Buff1[0] & 255) + 1 == nTurn)) {
                            CmdIng = false;
                            return 0;
                        }
                        nTurn = nTurn - (Buff1[0] & 255) - 1;
                        memcpy(Buff1, (Buff1[0] & 255) + 1, Buff2, 0, nTurn);
                        ArrayClear(Buff1, 5000);
                        memcpy(Buff2, 0, Buff1, 0, nTurn);
                    }
                }
            }
            CmdIng = false;
            return -1;
        } catch (Exception e) {
            return -1;
        }
    }

    public static int Inventory_G2(byte QValue, byte Session, byte AdrTID, byte LenTID,
                                   byte TIDFlag, int[] CardNum, byte[] EPCList, int[] EPCLength) {
        try {
            byte[] Msg = new byte[10];
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 1;
            Msg[3] = QValue;
            Msg[4] = Session;
            if (TIDFlag == 0) {
                Msg[0] = 6;
                getCRC(Msg, 5);
            } else {
                Msg[0] = 8;
                Msg[5] = AdrTID;
                Msg[6] = LenTID;
                getCRC(Msg, 7);
            }
            UhfService.target_chara.setValue(Msg);
            ;
            ArrayClear(RecvBuff, 300);
            RecvLength = 0;
            UhfService.RecvString = "";
            mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
            Log.d("Write data:", "AAAAAAAAAAAAAAAAA");
            if (GetInventoryData() == 0) {
                byte[] szBuff = new byte[3000];
                byte[] szBuff1 = new byte[3000];
                memcpy(RecvBuff, 0, szBuff, 0, RecvLength);
                int Nlen = 0;
                while (RecvLength > 0) {
                    int nLenszBuff = (szBuff[0] & 255) + 1;
                    if ((szBuff[3] == 0x01) || (szBuff[3] == 0x02) || (szBuff[3] == 0x03) || (szBuff[3] == 0x04)) {
                        //*Ant=szBuff[4];
                        CardNum[0] += (szBuff[5] & 255);
                        memcpy(szBuff, 6, szBuff1, Nlen, (szBuff[0] & 255) - 7);
                        Nlen += ((szBuff[0] & 255) - 7);
                        if ((RecvLength - (szBuff[0] & 255) - 1) > 0) {
                            byte[] daw = new byte[3000];
                            memcpy(szBuff, (szBuff[0] & 255) + 1, daw, 0, RecvLength - (szBuff[0] * 255) - 1);
                            ArrayClear(szBuff, 3000);
                            memcpy(daw, 0, szBuff, 0, RecvLength - (szBuff[0] * 255) - 1);
                        }
                    }
                    RecvLength = RecvLength - nLenszBuff;
                }
                memcpy(szBuff1, 0, EPCList, 0, Nlen);
                EPCLength[0] = Nlen;
                return szBuff[3];
            }
            return 0x30;
        } catch (Exception e) {
            return 0x30;
        }
    }

    public static int ReadData_G2(byte Enum, byte[] EPC, byte Mem, byte WordAddr, byte Num, byte[] Psd, byte[] Data) {
        try {
            byte[] Msg = new byte[200];
            Msg[0] = (byte) (12 + Enum * 2);
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 0x02;
            Msg[3] = Enum;
            for (int i = 0; i < Enum * 2; i++) {
                Msg[4 + i] = EPC[i];
            }
            Msg[4 + Enum * 2] = Mem;
            Msg[5 + Enum * 2] = WordAddr;
            Msg[6 + Enum * 2] = Num;
            Msg[7 + Enum * 2] = Psd[0];
            Msg[8 + Enum * 2] = Psd[1];
            Msg[9 + Enum * 2] = Psd[2];
            Msg[10 + Enum * 2] = Psd[3];
            getCRC(Msg, 11 + Enum * 2);
            CmdTime = 500;
            int Len = 13 + Enum * 2;
			 /*byte[]data = new byte[Msg[0]+1];
			 memcpy(Msg,0,data,0,Msg[0]+1);
			 MyService.target_chara.setValue(data); 
			 mBluetoothLeService.writeCharacteristic(MyService.target_chara);
			 Log.d("write:", bytesToHexString(data,0,Msg[0]+1));*/
            boolean SendFlag = true;
            while (SendFlag) {
                if ((Len - 20) > 0) {
                    byte[] data = new byte[20];
                    memcpy(Msg, 0, data, 0, 20);
                    byte[] daw = new byte[200];
                    memcpy(Msg, 20, daw, 0, Len - 20);
                    memcpy(daw, 0, Msg, 0, Len - 20);
                    Len = Len - 20;
                    UhfService.target_chara.setValue(data);
                    mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
                    Log.d("write:", bytesToHexString(data, 0, 20));
                } else {
                    SystemClock.sleep(100);
                    byte[] data = new byte[Len];
                    memcpy(Msg, 0, data, 0, Len);
                    UhfService.target_chara.setValue(data);
                    mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
                    Log.d("write:", bytesToHexString(data, 0, Len));
                    SendFlag = false;
                }
            }
            ArrayClear(RecvBuff, 300);
            RecvLength = 0;
            UhfService.RecvString = "";
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                if (RecvBuff[3] == 0) {
                    memcpy(RecvBuff, 4, Data, 0, RecvLength - 6);
                    return 0;
                }
                return -1;
            }
            return -1;
        } catch (Exception e) {
            return 0x30;
        }
    }

    public static int WriteData_G2(byte Enum, byte[] EPC, byte Mem, byte WordAddr, byte WNum, byte[] Psd, byte[] Data) {
        try {
            byte[] Msg = new byte[200];
            Msg[0] = (byte) (12 + Enum * 2 + WNum * 2);
            Msg[1] = (byte) (ComAddr & 255);
            Msg[2] = 0x03;
            Msg[3] = WNum;
            Msg[4] = Enum;
            for (int i = 0; i < Enum * 2; i++) {
                Msg[5 + i] = EPC[i];
            }
            Msg[5 + Enum * 2] = Mem;
            Msg[6 + Enum * 2] = WordAddr;
            for (int i = 0; i < WNum * 2; i++) {
                Msg[7 + Enum * 2 + i] = Data[i];
            }
            Msg[7 + Enum * 2 + WNum * 2] = Psd[0];
            Msg[8 + Enum * 2 + WNum * 2] = Psd[1];
            Msg[9 + Enum * 2 + WNum * 2] = Psd[2];
            Msg[10 + Enum * 2 + WNum * 2] = Psd[3];
            getCRC(Msg, 11 + Enum * 2 + WNum * 2);
            CmdTime = 500;
//			 mBluetoothLeService.writeCharacteristic(MyService.target_chara);
            int Len = 13 + Enum * 2 + WNum * 2;
            boolean SendFlag = true;
            while (SendFlag) {
                if ((Len - 20) > 0) {
                    byte[] data = new byte[20];
                    memcpy(Msg, 0, data, 0, 20);
                    byte[] daw = new byte[200];
                    memcpy(Msg, 20, daw, 0, Len - 20);
                    memcpy(daw, 0, Msg, 0, Len - 20);
                    Len = Len - 20;
                    UhfService.target_chara.setValue(data);
                    Log.d("write:", bytesToHexString(data, 0, 20));
                    mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
                } else {
                    SystemClock.sleep(100);
                    byte[] data = new byte[Len];
                    memcpy(Msg, 0, data, 0, Len);
                    UhfService.target_chara.setValue(data);
                    Log.d("write:", bytesToHexString(data, 0, Len));
                    mBluetoothLeService.writeCharacteristic(UhfService.target_chara);
                    SendFlag = false;
                }
            }
            ArrayClear(RecvBuff, 300);
            RecvLength = 0;
            UhfService.RecvString = "";
            if (GetData() == 0) {
                ComAddr = RecvBuff[1];
                if (RecvBuff[3] == 0) {
                    return 0;
                }
                return -1;
            }
            return -1;
        } catch (Exception e) {
            return 0x30;
        }
    }
}
